import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JOptionPane;

import java.awt.Color;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JTextField;
import javax.swing.JCheckBox;

//Patch wyamagany-log albo wiadomosc kiedy sie nie polaczymy.Sprawdzic na innym kompie.




public class Client {

	private JFrame frame;
	private static JFrame errorframe;
	private static JTextField InputStack;
	private static JLabel[] Card = new JLabel[5];
	private static JLabel[] PBank = new JLabel[7];
	private static JLabel[] PStake = new JLabel[7];
	private static JLabel[] PLabel = new JLabel[7];
	private static JLabel[] PMove = new JLabel[7];
	private static JButton[] Button = new JButton[5];
	private static JButton[] CardButton = new JButton[4];
	private static JLabel GamePula;
	private static JLabel MyStack;
	private static JLabel GameStatus;
	private static BufferedReader BR = null;
	private static InputStreamReader IR;
	private static BufferedWriter OS = null;
	private static int Min;
	public static boolean Moved2;
	public static JButton Discard;
	public static String[] Exchange = {"E","0","0","0","0"};
	public static int K;
	/**
	 * Launch the application.
	 */
	
	public static void main(String[] args) {
		
		 String hostname = "localhost";
		 int port = 5000;
		 Socket ClientSocket = null;   //socket of client
		 boolean connected = false;
		 K = 0;
		 
		 String Message = ""; 
		 String[] MS = null;
		 String Task = null;
		 
		 Card[0]  = new JLabel("NOTHING");
		 PBank[0] =  new JLabel("NOPLAYER");
		 PMove[0] = new JLabel("NOTHING");
		 PLabel[0]= new JLabel("NOTHING");
		 PStake[0]= new JLabel("NOTHING");

		 
		 
			try {
				ClientSocket = new Socket(hostname,port);
				connected = true;
				IR = new InputStreamReader(ClientSocket.getInputStream());
				BR = new BufferedReader(IR);     //our BufferReader to read input stream from the server
				OS = new BufferedWriter(new OutputStreamWriter(ClientSocket.getOutputStream()));   //Output stream!! 
				
			}catch (UnknownHostException e1) {
				System.out.println("Exception: " + e1);	
			}catch (IOException e1) {
				System.out.println("IOException: " + e1);}
			
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					try {
						Client window = new Client();
						window.frame.setVisible(true);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
			 
			
//-------------------------------------LOOP-------------------------------------------------------//			
			
			
			
		//We are connected to the server. Now Client started listening to the server messages!
		//The most important loop in client,responsilbe for communication with server!
		System.out.println("Client is listening to the Server!");
		while(connected){
			try {
				Message = "";
				Message = BR.readLine();
				//Message Picked Up
				MS = Message.split(",");
				Task = MS[0];  //the first char in the message is responsible for telling gui what kind of info is that
				Moved2 = false;
				Message = "";
				//System.out.println(" MS wynosi : "+ MS[0]);
				//System.out.println(" I wynosi : "+ K);
				
			
			}catch (IOException e) {
				e.printStackTrace();}
		
				switch (Task){
				
				case "H":  //Hand-> H TC 9D TS AH for instance [0]-task, [1]-> 1 hand where Task array of hands
					for(int i=1;i<=4;i++)
						UPDATE_HAND(MS,i);
					System.out.println("Hand received");
					break;
				case "B":         //B-->basic information from 0 to 5
					UPDATE_Basic_Info(MS[1],MS[2],MS[3],MS[4],MS[5],MS[6],MS[7]);
					System.out.println(MS[6]);
					break;
				case "C":
					for(int i=1;i<=6;i++)
						CLEAN_Up(MS);
					break;
				case "S":
					UPDATE_Stacks(MS);
					break;
				case "M":
					EnableButtons();
					K = K +1;
					Min = Integer.parseInt(MS[2]);
					GameStatus.setText("Now it's your turn!");
					
					if(MS[2].equals("0"))
						UPDATE_CHECK(true);
					else
						UPDATE_CHECK(false);
					
					try {
						Thread.sleep(8000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if(Moved2==true){
						System.out.println("MOVED");
					    GameStatus.setText("Moved, wait for your turn");}
						
					else{
						GameStatus.setText("Time out!");
						InfoServer("FOLD");
						DisableButtons();}
					
					break;
				case "G":
					UPDATE_GUI(MS[1],MS[2],MS[3],MS[4],MS[5]);
					break;
				case "ST": 
					UPDATE_Stack(MS[1]);
					break;
				case "DS": //Discard function
					EnableCard();
					
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					Discard(Exchange);
					Discard.setEnabled(false);
					DisableCard();
					break;
				case "CC":
					Message = "";
					MS[0] = "";
					Task = "";
					Moved2 = false;
					break;
				case "RC":
					CLEAN_STAKES();
					break;
				case "CR":
					CLEAN_MOVES();
					break;
				case "END":
					connected = false;
					break;
				}
				
		}
	
		 try {
			 OS.close();
			 BR.close();
		   	 ClientSocket.close();
		   	 System.out.println("Client Closed");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}



	/**
	 * Create the application.
	 */
	public Client() {
		initialize();
	}

	
	
//----------------------------------------Update_METHODS---------------------------------------------//	

	
	public void Moved(boolean X){
		Moved2 = true;
	}
	
	public static void UPDATE_GUI(final String I,final String L,final String MS,final String B,final String Min)
	{
		EventQueue.invokeLater(
				new Runnable(){
					
					public void run(){
						int i = Integer.parseInt(I)+1;
						PStake[i].setText(Min);
						PMove[i].setText(L);
						PBank[i].setText(MS);
						GamePula.setText(B);
						
										
					}
				}
			);
				
	}	
	public static void UPDATE_Stack(final String X){
		EventQueue.invokeLater(
				new Runnable(){
					
					public void run(){
						MyStack.setText(X);
										
					}
				}
			);
				
	}	
	
	
	public static void UPDATE_Stacks(final String[] Ms){
		EventQueue.invokeLater(
				new Runnable(){
					
					public void run(){
						for(int i=1;i<=Ms.length-1;i++)
							PBank[i].setText(Ms[i]);
										
					}
				}
			);
				
	}	
	
	public static void CLEAN_MOVES(){
		EventQueue.invokeLater(
				new Runnable(){
					
					public void run(){
						for(int i=1;i<=6;i++)
							PMove[i].setText("X");
										
					}
				}
			);
				
	}	
	
	
public static void CLEAN_Up(final String[] Ms){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=1;i<=6;i++)
						if(Ms[i].equals("D")){
							PMove[i].setVisible(false);
							PStake[i].setVisible(false);
							PBank[i].setVisible(false);
							PLabel[i].setVisible(false);}
									
				}
			}
		);
			
}

//-------------Method_For_Updating_Players_Hands--------------//

public static void UPDATE_HAND(final String[] Ms,final int i)	{  //paramters is array and what hand we are taking care of:1,2,3,4 0- is a task
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					Card[i].setText(Ms[i].charAt(0)+"");
					SetColour(Ms[i].charAt(1),i);
				
				}
			}
		);
}	


public static void CLEAN_STAKES()	{  //paramters is array and what hand we are taking care of:1,2,3,4 0- is a task
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=1;i<=6;i++)
						PStake[i].setText("0");
				
				}
			}
		);
}	


public static void UPDATE_CHECK(final boolean X){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					Button[2].setEnabled(X);				
				}
			}
		);
}

//Method responsible for seting up colours for GUI players hand!
public static void SetColour(final char C,final int i){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					if (C=='C')
						Card[i].setForeground(Color.GREEN);
					else if(C=='D')
						Card[i].setForeground(Color.BLUE);
					else if(C=='S')
						Card[i].setForeground(Color.BLACK);
					else 
						Card[i].setForeground(Color.RED);
				
				}
			}
		);

}

//---------------Method_For_Updating_Info_Before_Auction---------------------------//
public static void UPDATE_Basic_Info(final String B,final String  D,final String  MC,final String  DC,final String  Ms,final String T,final String BOOL)	{  //paramters is array and what hand we are taking care of:1,2,3,4 0- is a task
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					int turn = Integer.parseInt(T)+1;
					GamePula.setText(B);
					MyStack.setText(Ms);
					PLabel[Integer.parseInt(D)+1].setForeground(Color.GREEN);
					
					PStake[Integer.parseInt(MC)+1].setText("15");
					PStake[Integer.parseInt(DC)+1].setText("30");
					if(BOOL.equals("10"))
						GameStatus.setText("It's your turn!");
					else
						GameStatus.setText("Player"+turn+" is now having a turn!");
					
					PLabel[turn].setForeground(Color.RED);
					
					
				
				}
			}
		);
}	


public static void EnableButtons(){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=0;i<5;i++)
						Button[i].setEnabled(true);	
				
				InputStack.setEditable(true);
					
				}
			}
		);
}

public static void DisableButtons(){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=0;i<5;i++)
						Button[i].setEnabled(false);		
					
					InputStack.setEditable(false);
				}
			}
		);
}


public static void InfoServer(String S){
	try {
		OS.write(S);
		OS.newLine();
		OS.flush();	
	}catch (IOException e) {
		e.printStackTrace();}
	
	
}

public static void Discard(String[] E){
	String S ="E";
	for(int i=1;i<5;i++)
		S=S+","+E[i];
	System.out.println("Hand request sent:"     + S);
	try {
		OS.write(S);
		OS.newLine();
		OS.flush();	
	}catch (IOException e) {
		e.printStackTrace();}
}

public static void DisableCard(){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=0;i<4;i++)
						CardButton[i].setEnabled(false);	
					
				}
			}
		);
}

public static void EnableCard(){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					for(int i=0;i<4;i++)
						CardButton[i].setEnabled(true);		
					
				}
			}
		);
}

public static void SetText(final String S){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
						InputStack.setText(S);
					
				}
			}
		);
}

public static void Ex(final String S,final int x){
	EventQueue.invokeLater(
			new Runnable(){
				
				public void run(){
					Exchange[x] = S;
					
				}
			}
		);
}




/**
 * Initialize the contents of the frame.
 * @wbp.parser.entryPoint
 */
private void initialize() {
	frame = new JFrame();
	frame.setBounds(100, 100, 576, 344);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.getContentPane().setLayout(null);
	
	
	
//---------------------ActionButtons---------------------------//		
	
	Button[0] = new JButton("FOLD");
	Button[0].setFont(new Font("Dialog", Font.BOLD, 15));
	Button[0].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			InfoServer("FOLD");
			DisableButtons();
			Moved(true);
		}
	});
//------------------------------------------------------------//	
	Button[0].setBackground(Color.ORANGE);
	Button[0].setForeground(Color.RED);
	Button[0].setBounds(142, 250, 136, 55);
	frame.getContentPane().add(Button[0]);
//----------------------CALL--------------------------------------//		
	Button[1] = new JButton("CALL");
	Button[1].setFont(new Font("Dialog", Font.BOLD, 15));
	Button[1].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			InfoServer("CALL");
			DisableButtons();
			Moved(true);
		}
	});
//------------------------------------------------------------//	
	Button[1].setBackground(Color.ORANGE);
	Button[1].setForeground(Color.RED);
	Button[1].setBounds(280, 250, 136, 55);
	frame.getContentPane().add(Button[1]);
//---------------------CHECK-----------------------------------//		
	Button[2] = new JButton("CHECK");
	Button[2].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			InfoServer("CHECK");
			DisableButtons();
			Moved(true);
		}
	});
//------------------------------------------------------------//	
	Button[2].setForeground(Color.RED);
	Button[2].setBackground(Color.ORANGE);
	Button[2].setBounds(142, 218, 136, 25);
	frame.getContentPane().add(Button[2]);
	//--------------------ALLIN---------------------------------//		
	Button[3] = new JButton("ALL-IN");
	Button[3].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			InfoServer("ALLIN");
			DisableButtons();
			Moved(true);
		}
	});
	Button[3].setBackground(Color.RED);
	Button[3].setBounds(280, 218, 136, 25);
	frame.getContentPane().add(Button[3]);
//-------------------------BET/RAISE-----------------------------//	
	Button[4] = new JButton("BET/RAISE");
	Button[4].addActionListener(new ActionListener() {
		public synchronized void actionPerformed(ActionEvent arg0) {
			if(Integer.parseInt(InputStack.getText()) < Min ){
				SetText("Bet too low");
			}
			else if(Integer.parseInt(InputStack.getText())==Min){
				InfoServer("CALL");
				DisableButtons();
				System.out.println("Call made by a player");
				SetText("");}
			else if(Integer.parseInt(InputStack.getText())> Integer.parseInt(MyStack.getText()) ){
				InfoServer("ALLIN");
				DisableButtons();
				Moved(true);}
			else{
				InfoServer("BR,"+InputStack.getText());
				DisableButtons();
				SetText("");
				System.out.println("Raise/bet made by a player ");
				Moved(true);
				}
		}
	});
//------------------------------------------------------------//	
	Button[4].setBackground(Color.ORANGE);
	Button[4].setBounds(425, 218, 117, 44);
	frame.getContentPane().add(Button[4]);
	
	InputStack = new JTextField();
	InputStack.setEditable(false);
	InputStack.setBounds(425, 268, 118, 22);
	frame.getContentPane().add(InputStack);
	InputStack.setColumns(10);
	InputStack.setText("");

	for(int i=0;i<5;i++)
		Button[i].setEnabled(false);
	
	
//---------------------HoodLabels--------------------------//		
	
	JLabel PulaLabel = new JLabel("PULA: ");
	PulaLabel.setBounds(12, 12, 106, 15);
	frame.getContentPane().add(PulaLabel);
	
	JLabel MyChipsLabel = new JLabel("$");
	MyChipsLabel.setBounds(12, 36, 70, 15);
	frame.getContentPane().add(MyChipsLabel);
	
	JLabel StakeLabel = new JLabel("STAKE");
	StakeLabel.setBounds(266, 0, 70, 15);
	frame.getContentPane().add(StakeLabel);
	
	JLabel InPlayLabel = new JLabel("IN-PLAY");
	InPlayLabel.setBounds(348, 0, 70, 15);
	frame.getContentPane().add(InPlayLabel);
	
	JLabel BankLabel = new JLabel("BANK");
	BankLabel.setBounds(438, 0, 70, 15);
	frame.getContentPane().add(BankLabel);
	
//------------------PLAYERLABELS-----------------------//		
	
	PLabel[1] = new JLabel("Player1:");
	PLabel[1].setBounds(163, 23, 70, 15);
	frame.getContentPane().add(PLabel[1]);
	
	PLabel[2] = new JLabel("Player2:");
	PLabel[2].setBackground(new Color(255, 0, 0));
	PLabel[2].setBounds(163, 50, 70, 15);
	frame.getContentPane().add(PLabel[2]);
	
	PLabel[3] = new JLabel("Player3:");
	PLabel[3].setBounds(163, 77, 70, 15);
	frame.getContentPane().add(PLabel[3]);
	
	PLabel[4] = new JLabel("Player4:");
	PLabel[4].setBounds(163, 104, 70, 15);
	frame.getContentPane().add(PLabel[4]);
	
	PLabel[5] = new JLabel("Player5:");
	PLabel[5].setBounds(163, 131, 70, 15);
	frame.getContentPane().add(PLabel[5]);
	
	PLabel[6] = new JLabel("Player6:");
	PLabel[6].setBounds(163, 155, 70, 15);
	frame.getContentPane().add(PLabel[6]);
	
//----------------------CARD_BUTTONS-------------------------//		
	
	CardButton[0]= new JButton("1");
	CardButton[0].setBackground(new Color(0, 128, 128));
	CardButton[0].setForeground(new Color(0, 0, 0));
	CardButton[0].setFont(new Font("Dialog", Font.BOLD, 10));
	CardButton[0].setBounds(0, 168, 57, 35);
	frame.getContentPane().add(CardButton[0]);
	CardButton[0].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			CardButton[0].setEnabled(false);
			Ex("1",1);
		}
	});

	
	CardButton[1] = new JButton("2");
	CardButton[1].setForeground(new Color(0, 0, 0));
	CardButton[1].setBackground(new Color(0, 128, 128));
	CardButton[1].setFont(new Font("Dialog", Font.BOLD, 10));
	CardButton[1].setBounds(57, 168, 57, 35);
	frame.getContentPane().add(CardButton[1]);
	CardButton[1].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			CardButton[1].setEnabled(false);
			Ex("1",2);
		}
	});
	
	CardButton[2] = new JButton("3");
	CardButton[2].setForeground(new Color(0, 0, 0));
	CardButton[2].setBackground(new Color(0, 128, 128));
	CardButton[2].setFont(new Font("Dialog", Font.BOLD, 10));
	CardButton[2].setBounds(0, 200, 57, 35);
	frame.getContentPane().add(CardButton[2]);
	CardButton[2].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			CardButton[2].setEnabled(false);
			Ex("1",3);
		}
	});
	
	CardButton[3] = new JButton("4");
	CardButton[3].setBackground(new Color(0, 128, 128));
	CardButton[3].setForeground(new Color(0, 0, 0));
	CardButton[3].setFont(new Font("Dialog", Font.BOLD, 10));
	CardButton[3].setBounds(57, 200, 57, 35);
	frame.getContentPane().add(CardButton[3]);
	CardButton[3].addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			CardButton[3].setEnabled(false);
			Ex("1",4);
		}
	});
	
	DisableCard();
	
	
	
//------------------AdditionalLabels-----------------//		
	
	JLabel MyHandLabel = new JLabel("My Hand:");
	MyHandLabel.setBounds(27, 144, 70, 15);
	frame.getContentPane().add(MyHandLabel);
	
	Discard = new JButton("Discard");
	Discard.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent arg0) {
			
		}
	});
	Discard.setForeground(new Color(0, 0, 0));
	Discard.setBackground(new Color(0, 128, 128));
	Discard.setFont(new Font("Dialog", Font.BOLD, 13));
	Discard.setBounds(20,100,90,40);
	frame.getContentPane().add(Discard);
	Discard.setEnabled(false);
	

//--------------------StakeLabels----------------------//
	
	PStake[1] = new JLabel("x.x");
	PStake[1].setBounds(266, 23, 70, 15);
	frame.getContentPane().add(PStake[1]);
	
	PStake[2] = new JLabel("x.x");
	PStake[2].setBounds(266, 50, 70, 15);
	frame.getContentPane().add(PStake[2]);
	
	PStake[3] = new JLabel("x.x");
	PStake[3].setBounds(266, 77, 70, 15);
	frame.getContentPane().add(PStake[3]);
	
	PStake[4] = new JLabel("x.x");
	PStake[4].setBounds(266, 104, 70, 15);
	frame.getContentPane().add(PStake[4]);
	
	PStake[5] = new JLabel("x.x");
	PStake[5].setBounds(266, 131, 70, 15);
	frame.getContentPane().add(PStake[5]);
	
	PStake[6] = new JLabel("x.x");
	PStake[6].setBounds(266, 155, 70, 15);
	frame.getContentPane().add(PStake[6]);
	
//-------------------PBANK_LABELS--------------------------//
	
	PBank[2] = new JLabel("x.x");
	PBank[2].setBounds(438, 50, 70, 15);
	frame.getContentPane().add(PBank[2]);
	
	PBank[1] = new JLabel("x.x");
	PBank[1].setBounds(438, 27, 70, 15);
	frame.getContentPane().add(PBank[1]);
	
	PBank[3] = new JLabel("x.x");
	PBank[3].setBounds(438, 77, 70, 15);
	frame.getContentPane().add(PBank[3]);
	
	PBank[4] = new JLabel("x.x");
	PBank[4].setBounds(438, 104, 70, 15);
	frame.getContentPane().add(PBank[4]);
	
	PBank[5] = new JLabel("x.x");
	PBank[5].setBounds(438, 131, 70, 15);
	frame.getContentPane().add(PBank[5]);
	
	PBank[6] = new JLabel("x.x");
	PBank[6].setBounds(438, 155, 70, 15);
	frame.getContentPane().add(PBank[6]);
	
//------------------PMOVE_LABELS--------------------//	
	
	PMove[1] = new JLabel("...");
	PMove[1].setBounds(348, 23, 70, 15);
	frame.getContentPane().add(PMove[1]);
	
	PMove[2] = new JLabel("...");
	PMove[2].setBounds(348, 50, 70, 15);
	frame.getContentPane().add(PMove[2]);
	
	PMove[3] = new JLabel("...");
	PMove[3].setBounds(348, 77, 70, 15);
	frame.getContentPane().add(PMove[3]);
	
	PMove[4] = new JLabel("...");
	PMove[4].setBounds(348, 104, 70, 15);
	frame.getContentPane().add(PMove[4]);
	
	PMove[5] = new JLabel("...");
	PMove[5].setBounds(348, 131, 70, 15);
	frame.getContentPane().add(PMove[5]);
	
	PMove[6] = new JLabel("...");
	PMove[6].setBounds(348, 155, 70, 15);
	frame.getContentPane().add(PMove[6]);
	
//-------------------MyBasicInfo-----------------------//
	
	GamePula = new JLabel("0");
	GamePula.setBounds(57, 12, 70, 15);
	frame.getContentPane().add(GamePula);
	
	MyStack = new JLabel("x");
	MyStack.setBounds(27, 36, 70, 15);
	frame.getContentPane().add(MyStack);
	
	GameStatus = new JLabel("Game Status: Waiting ...");
	GameStatus.setBounds(163, 191, 379, 15);
	frame.getContentPane().add(GameStatus);
	
//-------------------PlayerCardLabels----------------------//
	
	Card[3] = new JLabel("\"x\"");
	Card[3].setBounds(12, 270, 45, 15);
	frame.getContentPane().add(Card[3]);
	
	
	Card[1] = new JLabel("\"x\"");
	Card[1].setBounds(12, 250, 32, 12);
	frame.getContentPane().add(Card[1]);
	
	Card[2] = new JLabel("\"x\"");
	Card[2].setBounds(57, 250, 70, 15);
	frame.getContentPane().add(Card[2]);
	
	Card[4] = new JLabel("\"x\"");
	Card[4].setBounds(57, 270, 70, 15);
	frame.getContentPane().add(Card[4]);
	
	
	
}	
}
